package controllers;

import play.mvc.Controller;

import play.*;
import play.data.validation.Required;
import play.mvc.*;

import java.util.*;

import com.sun.xml.internal.stream.Entity;

import models.*;

//Created By C2 , Author IK_Ibrahim Kessba
@With(Secure.class)
// this class is used for the login, Doaa El-Hawary
public class Organizations extends Controller {

	public static void index() {
		render();
	}

	/**
	 * renders the view of the home page of the organization
	 * 
	 * @author Rania Nader Saeed
	 * @version 2011.05.06
	 * @category none
	 * @param void
	 * @return void
	 */
	public static void organizationHome(long OrganizationId, String msg) {

		// Msg this will be Used to Display the Error and the Success In
		// Responding to the Requests_Ibrahim Kessba
		if (msg == null) {
			msg = " default Message";
		}
		// Temprearly Assigned organization id = 2 for Testing Reasons_Ibrahim
		// Kessba
		OrganizationId = 2;
		Organization orgTemp = Organization.findById(OrganizationId);
		render(orgTemp, msg);
	}

	/**
	 * View for the Organiztion Profile
	 * 
	 * @author Ibrahim Kessba
	 */
	public static void orgProfile() {
		render();
	}

	/**
	 * renders all the organizations on the system
	 * 
	 * @author Rania Nader Saeed
	 * @version 2011.05.06
	 * @category none
	 * @param void
	 * @return void
	 */
	public static void viewAllOrganizations() {
		List orgs = Organization.findAll();
		render(orgs);
	}

	/**
	 * calls show.html in Organizations folder which renders based on the Idea
	 * id for instance a user would click on a link surrounded with <a
	 * href="@Organizations.show(topic.id)"></a> the method then check a couple
	 * of things before rendering
	 * 
	 * @author Amr Draz
	 * @version 2011.05.03
	 * @category C4S14
	 * @param id
	 *            : id of the topic that is to be shown
	 * @return none
	 */

	public static void show(long id) {

		Organization organization = Organization.findById(id);
		// / Draz's check for org privacy
		String username = Security.connected();
		User user = User.findByUsername(username);
		if (organization.isPrivate() && !(organization.isMember(user)))
			render("errors/503.html");

		// end draz part
		System.out.println(organization.id + "inside showorg");
		System.out.println(organization.getName());

		render(organization, user);
	}

	/**
	 * A user can creates an organization
	 * 
	 * @author Mostafa Badr
	 * @version 2010.0424
	 * @category C2D12
	 * @params name of the organization , the user , description of the
	 *         organization the type and structure
	 * @return false if the name of the organization is already found in the
	 *         system else return true
	 */

	public static boolean createOrganization(String name, User lead,
			String discription, String privacy) {

		List<Organization> o = Organization.findAll();
		for (int i = 0; i < o.size(); i++) {
			if (o.get(i).getName() == name)
				return false;
		}

		Organization organization = new Organization(name, lead, discription,
				privacy);
		organization.save();

		render();

		return true;
	}

	/**
	 * AS a leader in secret organization, I can invite idea developer to the
	 * organization
	 * 
	 * @author Mohamed Shalaby
	 * @version 2011.04.26
	 * @category C2 S4
	 * @param sender
	 *            : the sender of the invitation, receiver: the receiver user,
	 *            o: the organization of the sender,content: the content of the
	 *            invitation, date : the date of the notification
	 * @return True : invitation send successfully , False : invitation not send
	 */

	public static void InviteIdeaDeveloperToSecretOrg(long senId, long recId,
			long orgId, String content) {

		User sender = User.findById(senId);
		User receiver = User.findById(recId);
		Organization organization = Organization.findById(orgId);
		String message = "";
		if (organization.getPrivacy().equalsIgnoreCase("Secret")) {
			if (sender.getUserType(organization).equalsIgnoreCase("Lead")) {
				if (!organization.getMembers().contains(receiver)) {

					Invitation i = new Invitation(sender, receiver, content);
					i.save();
					message = "Invitation sent successfully";
					render(senId, recId, orgId, content, message);
				} else {
					message = "User already follow this organization";
					render(message);
				}
			} else {
				message = "The sender can't send this invitation unless he is the leader";
				render(message);
			}
		} else {
			message = "This organization is not secret";
			render(message);
		}
	}

	/**
	 * helper to pass the organization id to the helperInviteToOrg.html file
	 * 
	 * @author Mohamed Shalaby
	 * @version 2011.05.05
	 * @category C2 S4
	 * @param orgId
	 *            : the id of the organization that will send to the view
	 * @return void : nothing
	 */
	public static void helperInviteToOrg(long orgId) {
		render(orgId);
	}

	/**
	 * AS an organizer in secret organization , I can invite idea developer to
	 * certain entity in the organization
	 * 
	 * @author Mohamed Shalaby
	 * @version 2011.04.26
	 * @category C2 S5
	 * @param sender
	 *            : the sender of the invitation, receiver: the receiver user,
	 *            o: the organization of the sender,e : the entity in the
	 *            organization ,content: the content of the invitation, date :
	 *            the date of the notification
	 * @return True : invitation send successfully , False : invitation not send
	 */

	public static void InviteIdeaDeveloperToEntityInSecretOrg(long senId,
			long recId, long orgId, long entId, String content) {

		User sender = User.findById(senId);
		User receiver = User.findById(recId);
		Organization organization = Organization.findById(orgId);
		Eentity entity = Eentity.findById(entId);
		String message = "";
		if (organization.getPrivacy().equalsIgnoreCase("Secret")) {
			if (sender.getUserType(organization).equalsIgnoreCase("Organiser")) {
				if (!entity.getMembers().contains(receiver)) {
					Invitation k = new Invitation(sender, receiver, content,
							entity);
					k.save();
					message = "Invitation sent successfully";

					render(senId, recId, orgId, entId, content, message);
				} else {
					message = "User already follow this entity";
					render(message);
				}
			} else {
				message = "The sender can't send this invitation unless he is an organizer";
				render(message);
			}
		} else {
			message = "This organization is not secret";
			render(message);
		}

	}

	/**
	 * helper to send the entity id and the organization id of the entity to
	 * helperInviteToEntInOrg.html file
	 * 
	 * @author Mohamed Shalaby
	 * @version 2011.04.26
	 * @category C2 S5
	 * @param entId
	 *            : the id of the Entity that will send to the view
	 * @return void : nothing
	 */

	public static void helperInviteToEntInOrg(long entId) {
		Eentity e = Eentity.findById(entId);
		long orgId = e.getOrganization().getId();
		render(orgId, entId);
	}

	/**
	 * an organization lead enabeling users to create their tags
	 * 
	 * @author Mostafa Badr
	 * @version 2010.0428
	 * @category C2D9
	 * @params name of the organization , the user , the receiver
	 * @return true if the sender is an organization lead and the receiver is in
	 *         the organization else false
	 */

	public static boolean enableUsersToCreateTags(long organizationId,
			long senderId, long receiverId) {
		Organization organization = Organization.findById(organizationId);
		User sender = User.findById(senderId);
		User reciever = User.findById(receiverId);

		if (sender.getUserType(organization).equalsIgnoreCase("Lead")
				&& organization.getMembers().contains(reciever)) {

			LinkedList<Role> test = (LinkedList<Role>) reciever.getRoleList();
			for (int i = 0; i < test.size(); i++) {

				if (test.get(i).getRelatedOrganization().getId() == organization
						.getId()) {
					reciever.getRoleList().get(i).setUserCanTag(true);
					return true;
				}

			}

		}

		return false;

	}

	/**
	 * Idea Developer Send Request to Join Public Organization
	 * 
	 * @author Ibrahim Kessba
	 * @version 2011.04.29
	 * @category C2S6
	 * @params userTempId : User Wanting to join the Organization ,
	 *         organizationToBeJoined : Organization to be joined
	 * @return Boolean True : Successful joining request False: User Already
	 *         Member in this Organization
	 */

	public static boolean requestToJoinPublicOrganization(
			long organizationToBeJoinedId) {

		// Getting the Object User by it's Equivlant Id_IK

		String username = Security.connected();
		User userTemp = User.findByUsername(username);

		Organization organizationToBeJoined = Organization
				.findById(organizationToBeJoinedId);

		// Getting all the Users in this organization_IK

		LinkedList organizationMembersList = organizationToBeJoined
				.getMembers();

		// Check that the Organization is Public,Terminate Otherwise_IK

		if (organizationToBeJoined.getPrivacy().equals("Public")) {
			System.out
					.println("/n WARNING : Request Cannot Be Made Beacuse Organization is Not Public !! /n");
			return false;
		}

		// Check that the userTemp is not in the organization_IK
		if (organizationMembersList.contains(userTemp)) {
			System.out.println("User Name : " + userTemp
					+ "User is Already Following " + organizationToBeJoined
					+ " Organization");
			return false; // Already in Followers List
		}

		// Adding the User to the Organization List of members
		organizationMembersList.add(userTemp);

		System.out.println("User Name : " + userTemp + "Joined The "
				+ organizationToBeJoined + " Organization");
		organizationToBeJoined.setMembers(organizationMembersList);
		return true;
	}

	/**
	 * Send To Join Private Orgnization As An Idea Devleopler
	 * 
	 * @author Ibrahim Kessba
	 * @version 2011.04.29
	 * @category C2S7
	 * @param organizationToBeJoinedId
	 *            : Organization id
	 * @return True : Request Send to Organization , False : Reuqest Wasn't Send
	 *         due to an error
	 */

	public static boolean RequestToJoinPrivateOrganization(
			long organizationToBeJoinedId) {

		// Getting the Object User by it's Equivlant Id_IK

		String username = Security.connected();
		User userToJoinId = User.findByUsername(username);

		Organization organizationToBeJoined = Organization
				.findById(organizationToBeJoinedId);

		// Getting the User object by id
		User tempUser = User.findById(userToJoinId);

		// Cheking that the Organization is Private
		if (organizationToBeJoined.getPrivacy().equals("Private")) {
			System.out
					.println("/n WARNING : Request Cannot Be Made Organization is Not Private !! /n");
			return false;
		}

		// Implementing Send Request to Join An Organization

		String msg = "";
		Request requestToJoin = new Request();
		requestToJoin.setSender(tempUser);
		requestToJoin.setReciever(organizationToBeJoined.getLead());
		requestToJoin.setType("join");
		requestToJoin.setContent("Idea developer " + tempUser.getfName()
				+ "Wants to Join" + organizationToBeJoined.getName());

		return true;
	}

	/**
	 * a method that sets the privacy of a certain organization as public,
	 * private or secret
	 * 
	 * 
	 * @author Ebtehal Abed
	 * @version 2011.04.30
	 * @category C2S3
	 * @param Organization
	 *            : inwhich the method will be performed Type privacy: the type
	 *            which the user wants the organization to be set to
	 * @return void
	 */

	public static void editPrivacy(String privacy, Long organizationID) {

		String username = Security.connected();
		Organization organization = Organization.findById(organizationID);
		User user = User.findByUsername(username);
		String result = "";

		if (user.equals(organization.getLead())) {
			organization.setPrivacyToOrganization(privacy);
			result = "Organization is now " + privacy;
			// renderTemplate("Organizations/viewOrganization", result);
		}
		result = "SORRY ! You are not authorized to edit the privacy level";
		// renderTemplate("Organizations/viewOrganization", result);
	}

	/**
	 * Checking that the Loged in User is Of Rank Lead to access this Page ,
	 * Getting all the Requests Belonging to this Organization
	 * @author Ibrahim Kessba
	 * @version 2011.0502
	 * @category C2S8
	 * @params OrganizationId: Organization Id In the database , Sent by the
	 *         Organization Home
	 * @return void
	 */

	public static void respondToRequests(long organizationId) {

		// Just for Trial And testing Purposes
		organizationId = 2;
		Organization organizationTemp = Organization.findById(organizationId);
		String username = Security.connected();
		User user = User.findByUsername(username);

		List<Request> orgRequests = organizationTemp.getRequests();

		if (organizationTemp.getRequests().size() == 0) {
			organizationHome(organizationId,
					"fail : Sorry There Are No Reuqest to Respond for this Organization");
		}
		if (organizationTemp.getLead() != user) {
			// User is Not Authorized
			organizationHome(organizationId,
					"fail : User are not Authorize to Acces this Page");
		}

		render(organizationTemp, orgRequests);

	}

	/**
	 * The Logic for Organization Lead Responding To Organization Requests :
	 * Approve Or Reject
	 * @author Ibrahim Kessba
	 * @version 2011.0502
	 * @category C2S8
	 * @params organizationTempId: Organization having Joining Requestes ,
	 *         requestId :Id of the Request have been Responded by the Organizer
	 *         Lead, respond : The Respond Made by the Organizer
	 * @return void
	 */
	public static void respondToRequestsLogic(long organizationTempId,
			long requestId, boolean respond) {

		String username = Security.connected();
		User user = User.findByUsername(username);

		Organization organizationTemp = Organization
				.findById(organizationTempId);

		Request tempRequest = Request.findById(requestId);

		String feedback = (respond ? "Approved" : "Rejected");

		String msg = "Request Have been  " + feedback;

		organizationHome(organizationTempId, msg);
		// render(organizationTemp);

	}

	/*
	 * public static void viewOrganization(long organizationID){ Organization
	 * organization = Organization.findById(organizationID);
	 * render(organization); }
	 */

}